
#include <BGeometry>
#include <BElement>
#include "member_BElement.h"
#include "member_BObject.h"

using namespace BWE;

#define member					(*(member_BElement*)_ptr)
#define member_allocate()		_ptr = new member_BElement(this)
#define member_release()		delete (member_BElement*)_ptr

extern BArray<BUInt>	UnusedTextureObjects;
extern BArray<BUInt>	UnusedFrameBufferObjects;
extern BArray<BUInt>	UnusedRenderBufferObjects;
extern BArray<BUInt>	UnusedProgramObjects;
extern BArray<BUInt>	UnusedShaderObjects;
extern BArray<BUInt>	UnusedListObjects;

BElement::BElement()
{
	member_allocate();
}
BElement::BElement(Primitive primitive, int first, int count)
{
	member_allocate();
	member.primitive = primitive;
	member.first = first;
	member.count = count;
	member.dirtyList = true;
}
BElement::BElement(Primitive primitive, BIntArray* indices)
{
	member_allocate();
	member.primitive = primitive;
	member.first = 0;
	if (indices)
	{
		member.count = indices->size();
		member.indices = indices;
		member.dirtyList = true;
	}
}
BElement::BElement(const BElement& other)
{
	member_allocate();
	member.primitive = other.primitive();
	member.first = other.first();
	member.count = other.count();
	member.indices = new BIntArray(*other.indices());
	member.pieces = new BPieceArray(*other.pieces());
}
BElement::~BElement()
{
	if (member.listName)
	{
		UnusedListObjects.append(member.listName);
		member.listName = 0;
	}
	member_release();
}

void BElement::copy(const BElement* other)
{
	object_member(this)->name = object_member(other)->name;
	member.visible = element_member(other)->visible;
	member.primitive = element_member(other)->primitive;
	member.first = element_member(other)->first;
	member.count = element_member(other)->count;
	member.indices = element_member(other)->indices;
	member.pieces = element_member(other)->pieces;
}
BElement* BElement::clone() const
{
	BElement* element = new BElement();
	element->copy(this);
	return element;
}

void BElement::set(Primitive primitive, int first, int count)
{
	member.primitive = primitive;
	member.first = first;
	member.count = count;
	member.dirtyList = true;
	if (member.geometry)
	{
		member.geometry->fresh();
	}
}

void BElement::setVisible(bool visible)
{
	if (member.visible != visible)
	{
		member.visible = visible;
		if (member.visible)
			this->emit(Signal_Show, true);
		else
			this->emit(Signal_Hide, false);
		if (member.geometry)
		{
			member.geometry->fresh();
		}
	}
}
bool BElement::visible() const
{
	return member.visible;
}

void BElement::setPrimitive(Primitive primitive)
{
	if (member.primitive != primitive)
	{
		member.primitive = primitive;
		member.dirtyList = true;
		if (member.geometry)
		{
			member.geometry->fresh();
		}
	}
}
Primitive BElement::primitive() const
{
	return member.primitive;
}

void BElement::setFirst(int first)
{
	if (first < 0)
		first = 0;
	if (member.first != first)
	{
		member.first = first;
		member.dirtyList = true;
		if (member.geometry)
		{
			member.geometry->fresh();
		}
	}
}
int BElement::first() const
{
	return member.first;
}

void BElement::setCount(int count)
{
	if (count < 0)
		count = 0;
	if (member.count != count)
	{
		member.count = count;
		member.dirtyList = true;
		if (member.geometry)
		{
			member.geometry->fresh();
		}
	}
}
int BElement::count() const
{
	return member.count;
}

void BElement::setIndices(BIntArray* indices)
{
	if (member.indices != indices)
	{
		member.indices = indices;
		member.dirtyList = true;
	}
	if (member.geometry)
	{
		member.geometry->fresh();
	}
}
const BIntArray* BElement::indices() const
{
	return member.indices;
}
BIntArray* BElement::indices()
{
	return member.indices;
}

void BElement::setPieces(BPieceArray* pieces)
{
	if (member.pieces != pieces)
	{
		member.pieces = pieces;
		member.dirtyList = true;
	}
	if (member.geometry)
	{
		member.geometry->fresh();
	}
}
const BPieceArray* BElement::pieces() const
{
	return member.pieces;
}
BPieceArray* BElement::pieces()
{
	return member.pieces;
}

const BBox& BElement::box() const
{
	return member.box;
}

BGeometry* BElement::geometry()
{
	return member.geometry;
}
const BGeometry* BElement::geometry() const
{
	return member.geometry;
}
